from deploy.remote.monitor import MonitoredService
from deploy.remote.monitor import ServiceStatus
import logging
import sys
logger = logging.getLogger(__name__)

class WindowsService(MonitoredService):
    '''Monitors windows services.
    
    # TODO: Add appropriate error handling for windows errors. E.g., vista can't 
    #    start or stop services without being elevated to administrator privileges.
    '''

    def __init__(self, host, shortName, descriptiveName):
        super(WindowsService, self).__init__(descriptiveName, host)
        self.shortName = shortName

        win32service = self._getWin32Service()
        self.STATUS_MAP = {
            win32service.SERVICE_RUNNING : ServiceStatus.RUNNING,
            win32service.SERVICE_START_PENDING : ServiceStatus.STARTING,
            win32service.SERVICE_STOP_PENDING : ServiceStatus.STOPPING,
            win32service.SERVICE_STOPPED : ServiceStatus.STOPPED
        }

    def _getWin32Service(self):
        import win32service
        return win32service

    def _getWin32ServiceUtil(self):
        import win32serviceutil
        return win32serviceutil

    def checkStatus(self):
        '''Override the base class method to check the current status of the service.'''
        win32serviceutil = self._getWin32ServiceUtil()

        win32serviceStatus = win32serviceutil.QueryServiceStatus(self.shortName, self.host)[1]
        serviceStatus = WindowsService.STATUS_MAP.get(win32serviceStatus, ServiceStatus.UNKNOWN)

        logger.debug('Status for service %s:%s: %s' % (self.host, self.name, serviceStatus))
        return serviceStatus

    def start(self):
        '''Start the windows service.'''
        logger.debug('Starting service %s:%s' % (self.host, self.name))
        win32serviceutil = self._getWin32ServiceUtil()
        win32serviceutil.StartService(self.shortName, self.host)

    def stop(self):
        '''Stop the windows service.'''
        logger.debug('Stopping service %s:%s' % (self.host, self.name))
        win32serviceutil = self._getWin32ServiceUtil()
        win32serviceutil.StopService(self.shortName, self.host)

class MockWindowsService(WindowsService):
    def __init__(self, *args, **kwargs):
        self.nextStatus = ServiceStatus.RUNNING

    def checkStatus(self):
        return self.nextStatus

    def start(self):
        self.nextStatus = ServiceStatus.RUNNING
        return ServiceStatus.STARTING

    def stop(self):
        self.nextStatus = ServiceStatus.STOPPED
        return ServiceStatus.STOPPING


if sys.platform != 'win32':
    WindowsService = MockWindowsService
